﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CID.Tests.Support;
using NUnit.Framework;
using CID.Domain.Infrastructure;
using Rhino.Mocks;

namespace CID.Domain.Tests.Infrastructure
{
    [TestFixture]
    class DeploymentAgentTests : BaseFunctionalTests
    {
        private const string Name = "Deployment Agent Name";
        private const string Address = "Deployment Agent Address";
        private DeploymentAgent deploymentAgent; 

        public override void SetUp()
        {
            base.SetUp();
            deploymentAgent = new DeploymentAgent(Name, Address);
        }

        #region Constructor
        [Test]
        public void CreateNewDeploymentAgent()
        {
            var deploymentAgent = new DeploymentAgent(Name, Address);

            Assert.AreEqual(Name, deploymentAgent.Name);
            Assert.AreEqual(Address, deploymentAgent.Address);
            Assert.IsTrue(deploymentAgent.Enabled);
            CollectionAssert.IsEmpty(deploymentAgent.Locations);
        }
        #endregion

        #region AddLocation
        [Test]
        public void AddLocation_FreshLocation_ShouldSucceed()
        {
            var location = Operations.StubsBuilder.BuildLocationStub();

            deploymentAgent.AddLocation(location);

            Assert.AreEqual(1, deploymentAgent.Locations.Count());
            Assert.AreEqual(deploymentAgent, location.DeploymentAgent);
            CollectionAssert.Contains(deploymentAgent.Locations, location);
        }

        [Test]
        public void AddLocation_AddItTwice_ShouldBeAddedOnlyOnce()
        {
            var location = Operations.StubsBuilder.BuildLocationStub();

            deploymentAgent.AddLocation(location);
            deploymentAgent.AddLocation(location);

            Assert.AreEqual(1, deploymentAgent.Locations.Count());
            Assert.AreEqual(deploymentAgent, location.DeploymentAgent);
            CollectionAssert.Contains(deploymentAgent.Locations, location);
        }

        [Test]
        public void AddLocation_FromAnotherLocation_ShouldSucceed()
        {
            var anotherDeploymentAgent = StubsBuilder.BuildDeploymentAgentStub();
            var location = Operations.StubsBuilder.BuildLocationStub(anotherDeploymentAgent);

            deploymentAgent.AddLocation(location);

            Assert.AreEqual(1, deploymentAgent.Locations.Count());
            Assert.AreEqual(deploymentAgent, location.DeploymentAgent);
            CollectionAssert.Contains(deploymentAgent.Locations, location);
            anotherDeploymentAgent.AssertWasCalled(x => x.RemoveLocation(location));
        }
        #endregion

        #region RemoveLocation
        [Test]
        public void RemoveLocation_LocationAlreadyAdded_ShouldSucceed()
        {
            var location1 = Operations.StubsBuilder.BuildLocationStub();
            var location2 = Operations.StubsBuilder.BuildLocationStub();
            deploymentAgent.AddLocation(location1);
            deploymentAgent.AddLocation(location2);

            deploymentAgent.RemoveLocation(location2);

            Assert.AreEqual(1, deploymentAgent.Locations.Count());
            Assert.AreEqual(deploymentAgent, location1.DeploymentAgent);
            Assert.IsNull(location2.DeploymentAgent);
            CollectionAssert.Contains(deploymentAgent.Locations, location1);
            CollectionAssert.DoesNotContain(deploymentAgent.Locations, location2);
        }

        [Test]
        public void RemoveLocation_LocationNotAdded_NothingShouldHappen()
        {
            var location1 = Operations.StubsBuilder.BuildLocationStub();
            var location2 = Operations.StubsBuilder.BuildLocationStub(StubsBuilder.BuildDeploymentAgentStub());
            deploymentAgent.AddLocation(location1);

            deploymentAgent.RemoveLocation(location2);

            Assert.AreEqual(1, deploymentAgent.Locations.Count());
            Assert.AreEqual(deploymentAgent, location1.DeploymentAgent);
            Assert.IsNotNull(location2.DeploymentAgent);
            CollectionAssert.Contains(deploymentAgent.Locations, location1);
            CollectionAssert.DoesNotContain(deploymentAgent.Locations, location2);
        }
        #endregion
    }
}
